package com.jerkin.server;

import com.jerkin.coder.DecoderHelper;
import com.jerkin.coder.EncoderHelper;
import com.jerkin.model.User;
import com.jerkin.request.RpcRequest;
import com.jerkin.serial.HessianSerializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.codec.string.StringEncoder;


/**
 * @version V1.0
 * @ClassName: RpcServer
 * @Description:
 * @author: huhongzhi
 * @date: 2021/4/11 22:31
 */
public class RpcServer {

    public static void start(String ip, Integer port, ChannelInboundHandler channelInboundHandler) {
        //创建boss线程组（有点像负责招人的包工头）
        NioEventLoopGroup boss = new NioEventLoopGroup();
        //创建建立链接的线程
        NioEventLoopGroup worker = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
        try {
            bootstrap.group(boss, worker)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EncoderHelper(User.class,new HessianSerializer()));
                            ch.pipeline().addLast(new DecoderHelper(RpcRequest.class,new HessianSerializer()));
                            ch.pipeline().addLast(channelInboundHandler);
                        }
                    });
            //bind初始化端口是异步的，但调用sync则会同步阻塞等待端口绑定成功
            ChannelFuture future = bootstrap.bind(ip, port).sync();
            System.out.println(ip + ":服务已启动,端口为：" + port);
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }

}
